using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using XjjXmm.Infrastructure.Exceptions;
using xjjxmm.infrastructure.Middleware.RateLimit.RateLimit;
using xjjxmm.infrastructure.ToolKit;
using XjjXmm.Infrastructure.User;
using xjjxmm.infrastructure.xjjxmmLog.LogKit;

namespace xjjxmm.infrastructure.Middleware.RepeatSubmit;

public class RepeatSubmitMiddleware : IMiddleware
{
    private readonly TokenContext _userContext;
    private readonly ILog<RepeatSubmitMiddleware> log;

    public RepeatSubmitMiddleware(TokenContext userContext, ILog<RepeatSubmitMiddleware> log)
    {
        _userContext = userContext;
        this.log = log;
    }

    public async Task InvokeAsync(HttpContext httpContext, RequestDelegate next)
    {
        var controllerActionDescriptor = httpContext
            .GetEndpoint()?
            .Metadata
            .GetMetadata<ControllerActionDescriptor>();

        var attribute = controllerActionDescriptor?.MethodInfo.GetCustomAttribute<RepeatSubmitAttribute>();
        if (attribute == null)
        {
            attribute = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttribute<RepeatSubmitAttribute>();
        }

        if (attribute == null)
        {
            await next(httpContext);
            return;
        }

        //var fullName = controllerActionDescriptor?.MethodInfo.DeclaringType?.FullName;
        // methondName =  controllerActionDescriptor?.MethodInfo.Name;
        //var paramters = controllerActionDescriptor?.MethodInfo.GetParameters();

        var controllerName = controllerActionDescriptor?.ControllerTypeInfo.FullName;
        var actionName = controllerActionDescriptor?.ActionName;
        var fullName = $"{controllerName}.{actionName}";

        httpContext.Request.EnableBuffering();
        using var reader = new StreamReader(httpContext.Request.Body);
        var requestBody = await reader.ReadToEndAsync();
        httpContext.Request.Body.Position = 0;

        var hashCode = requestBody.GetHashCode();

        var key = $"RepeatSubmit:{fullName}:{hashCode}";
        
        if(RedisKit.GetInstance().KeyExists(key)) {
            log.Information($"{key}:{requestBody}");
            throw new BussinessException("数据不能重复提交");
        }

        await RedisKit .GetInstance().StringSetAsync(key, "1", TimeSpan.FromMilliseconds(attribute.Interval));
        
        
        await next(httpContext);
    }
}